package com.zou.practice.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.BitFieldSubCommands;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * @author zouyaowen
 * @date 2020-09-03
 */
@RestController
@RequestMapping("/redis")
public class RedisController {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @GetMapping("/key-value")
    public void keyValue() {
        ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
        // key-value
        valueOperations.set("aaa", "aaa");
        // 批量key-value
        HashMap<String, String> multiMap = new HashMap<>(100);
        multiMap.put("aaa1", "aaa1");
        valueOperations.multiSet(multiMap);
        // 不存在则设置
        valueOperations.setIfAbsent("aaa2", "aaa2");
        // 存在则设置
        valueOperations.setIfPresent("aaa3", "aaa3");

        //valueOperations.bitField("2", new BitFieldSubCommands() );

        // 左边是头部，右边数据是尾部,push是添加，pop 是取出数据
        redisTemplate.opsForList().leftPush("list:hello-list", "hello1");
        redisTemplate.opsForList().leftPush("list:hello-list", "hello2");
        redisTemplate.opsForList().leftPush("list:hello-list", "hello3");
        // 取出数据
        String listValue = (String) redisTemplate.opsForList().leftPop("list:hello-list");
        System.out.println(listValue);
        redisTemplate.opsForSet().add("set:hello-set", "hello1");
        redisTemplate.opsForSet().add("set:hello-set", "hello2");
        redisTemplate.opsForSet().add("set:hello-set", "hello3");
        // ZSet是一种有序的Set，在保存数据的时候我们需要设置（double score），标识此内容的一个排序分值
        redisTemplate.opsForZSet().add("zset:hello-zset","hello1",1);
        redisTemplate.opsForZSet().add("zset:hello-zset","hello3",3);
        redisTemplate.opsForZSet().add("zset:hello-zset","hello2",2);
        // 使用分值范围的查询可以筛选出指定范围的内容
        Set set = redisTemplate.opsForZSet().rangeByScore("zset:hello-zset", 2, 3);


        HashMap<String, String> value = new HashMap<>();
        value.put("hello1", "hello1");
        value.put("hello2", "hello2");
        value.put("hello3", "hello3");
        redisTemplate.opsForHash().putAll("hash:hello-hash", value);
        Map<Object, Object> entries = redisTemplate.opsForHash().entries("hash:hello-hash");


        //HyperLogLog的主要作用是用来做基数统计。基数统计：一个集合中不重复元素的个数。
        String hyperKey = "HyperLog";
        // 在HyperLogLog中实际插入的内容为A-E
        String[] values = new String[] {"A","B","C","D","E","B","D"};
        redisTemplate.opsForHyperLogLog().add(hyperKey,values);
        Long size = redisTemplate.opsForHyperLogLog().size(hyperKey);

        redisTemplate.executePipelined(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
                return null;
            }
        });

        List<String> keyList = new ArrayList<>();
        // 使用Pipeline可以批量执行redis命令，防止多个命令建立多个连接
        // 读取
        List list = redisTemplate.executePipelined((RedisCallback) connection -> {
            keyList.forEach(key -> connection.get(null));
            return null;
        });
        // 写入
        redisTemplate.executePipelined((RedisCallback) connection -> {
            list.forEach(object -> {
                String key ="";
                // connection.set
            });
            return null;
        });

    }

}
